// 控制硬件与线程的库
#include <iostream>
#include "HardwareThread_RT.h"
#include <wiringPi.h>
#include <cmath>
// 安全关机函数
#include <sys/reboot.h>
#include <unistd.h>
#include "Globals.h"
#include "../AscDeepFileRT/DeepCMP_RT.h"
#include "../AscDeepFileRT/Preprocess_CMP_RT.h"
#include "Audio_RT_Process.h"
#include <thread>
// 初始化Key的GPIO
void Key_Gpio_Init(){
    // 初始化 wiringPi
    if (wiringPiSetup() == -1) {
        std::cerr << "wiringPi 初始化失败!" << std::endl;
    }
    // 设置 GPIO 引脚为输入模式，启用内部上拉电阻
    pinMode(BUTTON_PIN_VolUp, INPUT);
    pullUpDnControl(BUTTON_PIN_VolUp, PUD_UP);
    pinMode(BUTTON_PIN_VolDown, INPUT);
    pullUpDnControl(BUTTON_PIN_VolDown, PUD_UP);
    pinMode(BUTTON_PIN_Poweroff, INPUT);
    pullUpDnControl(BUTTON_PIN_Poweroff, PUD_UP);
}




void safeShutdown() {
    std::cout << "正在安全关机..." << std::endl;
    // 同步文件系统
    sync();
    // 调用 reboot 系统调用进行关机
    if (reboot(RB_POWER_OFF) == -1) {
        std::cerr << "关机系统调用失败" << std::endl;
        // 备用方案：尝试使用 system 命令
        std::system("sudo poweroff");
    }
}

// 按键控制的线程
void gpioMonitorThread() {
    std::cout << "开始监控 GPIO" << BUTTON_PIN_VolUp << " 的按键状态..." << std::endl;
    int lastState_VolUp = -1;
    int lastState_VolDown = -1;
    int lastState_Poweroff = 0;
    // 关机按键相关变量/用状态机实现关机(长按3s实现关闭)
    auto lastDebounceTime = std::chrono::steady_clock::now();
    const auto debounceDelay = std::chrono::milliseconds(50);

    while (true) {
        // 读取 GPIO 状态
        int currentState_VolUp = digitalRead(BUTTON_PIN_VolUp);
        int currentState_VolDown = digitalRead(BUTTON_PIN_VolDown);
        int currentState_Poweroff = digitalRead(BUTTON_PIN_Poweroff);
        // 只有当状态发生变化时才更新--音量增大
        if (currentState_VolUp != lastState_VolUp) {
            if(currentState_VolUp == 1) // 只有按下才进来
                {
                    improve_dB = improve_dB + 10; // 每次按下按键就增加10dB
                    improve_dB = std::min(improve_dB,60);
                    std::lock_guard<std::mutex> lock(gpio_mutex);
                    improve_gain = std::pow(10.0f, improve_dB / 20.0f);
                    std::cout << "音量增益dB" << improve_dB <<  std::endl;
                    std::cout << "音量增益Gain" << improve_gain <<  std::endl;
                    
                }
            // std::cout << "GPIO 状态变化: " << currentState_VolUp << std::endl;
            lastState_VolUp = currentState_VolUp;
        }
        // 只有当状态发生变化时才更新--音量减少
        if (currentState_VolDown != lastState_VolDown) {
            if(currentState_VolDown == 1) // 只有按下才进来
                {
                    improve_dB = improve_dB - 10; // 每次按下按键就减去10dB
                    improve_dB = std::max(improve_dB,0);
                    std::lock_guard<std::mutex> lock(gpio_mutex);
                    improve_gain = std::pow(10.0f, improve_dB / 20.0f);
                    std::cout << "音量增益dB" << improve_dB <<  std::endl;
                    std::cout << "音量增益Gain" << improve_gain <<  std::endl;
                }
            // std::cout << "GPIO 状态变化: " << currentState_VolDown << std::endl;
            lastState_VolDown = currentState_VolDown;
        }
        // 以下进行关机按键判断
        // 消抖处理
        if (currentState_Poweroff != lastState_Poweroff) {
            lastDebounceTime = std::chrono::steady_clock::now();
        }
        auto now = std::chrono::steady_clock::now();
        if (std::chrono::duration_cast<std::chrono::milliseconds>(
            now - lastDebounceTime).count() > debounceDelay.count()) {
            
            // 状态机处理
            switch (buttonState_Poweroff.load()) {
                case IDLE:
                    if (currentState_Poweroff == 1) {
                        buttonState_Poweroff = PRESSED;
                        pressStartTime = now;
                        std::cout << "按键按下" << std::endl;
                    }
                    break;
                    
                case PRESSED:
                    if (currentState_Poweroff == 0) {
                        buttonState_Poweroff = IDLE;
                        std::cout << "按键释放" << std::endl;
                    } else {
                        auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(
                            now - pressStartTime).count();
                        
                        if (elapsedTime >= 3000) {
                            buttonState_Poweroff = LONG_PRESSED;
                            std::cout << "检测到持续按下3秒!" << std::endl;
                            
                            // 执行关机操作
                            safeShutdown();
                        }
                    }
                    break;
                case LONG_PRESSED:
                    if (currentState_Poweroff == 0) {
                        buttonState_Poweroff = IDLE;
                        std::cout << "长按后释放" << std::endl;
                    }
                    break;
            }
        }
        lastState_Poweroff = currentState_Poweroff;
        // 添加消抖延迟
        delay(20);  // wiringPi 的延迟函数，单位毫秒
    }
}


// 声场分类相关代码
std::vector<int> envClassHistory;
const int HISTORY_SIZE = 5;
// 获取环境类别的字符串描述
std::string getEnvClassName(int env_class) {
    static const std::vector<std::string> ENV_CLASS_NAMES = {
        "干净语音", "音乐环境", "噪声环境", "含噪语音", "安静环境"
    };
    if (env_class >= 0 && env_class < static_cast<int>(ENV_CLASS_NAMES.size())) {
        return ENV_CLASS_NAMES[env_class];
    }
    return "未知类别(" + std::to_string(env_class) + ")";
}
int Find_MaxNumEnvironment(std::vector<int> envClassHistory){
    // 统计每个类别出现次数
    std::vector<int> counts(ENV_NUMS, 0);
    for (int envClass : envClassHistory) {
        if (envClass >= 0 && envClass < ENV_NUMS) {
            counts[envClass]++;
        }
    }
    // 找到出现次数最多的类别
    int maxCount = 0;
    int mostFrequent = -1;
    for (int i = 0; i < ENV_NUMS; i++) {
        if (counts[i] > maxCount) {
            maxCount = counts[i];
            mostFrequent = i;
        }
    }
    return mostFrequent;
}

// 音频归一化函数
void normalizeAudio(std::vector<float>& audioData) {
    if (audioData.empty()) return;
    
    // 方法1: 峰值归一化（推荐）
    float max_val = 0.0f;
    for (float sample : audioData) {
        max_val = std::max(max_val, std::abs(sample));
    }
    
    if (max_val > 1e-6f) { // 避免除以0
        float scale = 1.0f / max_val;
        for (float& sample : audioData) {
            sample *= scale;
        }
    }
}


// ASC识别的线程
void AscRknnThread(){
    while (true) {
        // 检查是否有数据需要处理
        if (Is_RKNN_Flag.load() == 1) {
            // 算一下帧能量
            // 计算RMS值
            float rms = calculateRMS(Input_RKNN);
            std::cout << "Audio RMS value: " << rms << std::endl;

            if (rms < 0.0005f) { // 阈值可根据实际情况调整
                Env_Class = 4;// 安静环境
                std::cout << "当前声场类别: 安静环境" <<  std::endl;
            } else {
                // 进行RKNN推理
                normalizeAudio(Input_RKNN);// 对输入音频进行归一化
                deepcmp.Run(Input_RKNN, mel_spectrogram,mel_filter_bank,Env_Class);
                std::string env_class_str;
                if (Env_Class == 0) {
                    env_class_str = "干净语音"; // "干净语音"
                } else if (Env_Class == 1) {
                    env_class_str = "音乐环境"; // "音乐环境"
                } else if (Env_Class == 2) {
                    env_class_str = "噪声环境"; // "噪声环境"
                } else if (Env_Class == 3) {
                    env_class_str = "含噪语音";
                } else {
                    env_class_str = "未知类别(" + std::to_string(Env_Class) + ")";
                }
                std::cout << "当前声场类别: " << env_class_str << std::endl;
                std::cout << "当前声场类别的数值: " << Env_Class << std::endl;
            }
            envClassHistory.push_back(Env_Class);// 把当前环境数据放到里面
            if(envClassHistory.size() >= HISTORY_SIZE){ // 当前环境数量超过了可统计的最大值
                int mostFrequent;
                mostFrequent = Find_MaxNumEnvironment(envClassHistory);
                Env_Class_Global.store(mostFrequent); // 存储全局变量
                std::cout << "最频繁的声场类别: " << getEnvClassName(mostFrequent) << std::endl;
                // 清空vector，size()变为0
                envClassHistory.clear();
            }
            
            // 推理完成后重置状态
            current_write_pos.store(0);
            std::fill(Input_RKNN.begin(), Input_RKNN.end(), 0.0f);
            Is_RKNN_Flag.store(0);
            } 
        else {
            // 无数据时短暂休眠，避免忙等待
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }
    }
}
